package com.vision.admin.user.cl.ui;

import net.customware.gwt.dispatch.client.DefaultExceptionHandler;
import net.customware.gwt.dispatch.client.DispatchAsync;
import net.customware.gwt.dispatch.client.standard.StandardDispatchAsync;

import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.SimpleBeanEditorDriver;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.core.client.Style.Side;
import com.sencha.gxt.widget.core.client.Window;
import com.sencha.gxt.widget.core.client.button.TextButton;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer;
import com.sencha.gxt.widget.core.client.event.SelectEvent;
import com.sencha.gxt.widget.core.client.form.PasswordField;
import com.sencha.gxt.widget.core.client.form.TextField;
import com.sencha.gxt.widget.core.client.form.error.SideErrorHandler;
import com.sencha.gxt.widget.core.client.tips.ToolTipConfig;
import com.vision.admin.cl.resource.AdminResources;
import com.vision.core.cl.BaseModule;
import com.vision.core.cl.Callback;
import com.vision.core.cl.CoreValidators;
import com.vision.core.cl.event.UserCreatedEvent;
import com.vision.core.cl.ui.UI;
import com.vision.core.cm.action.CreateUserAction;
import com.vision.core.cm.action.CreateUserResult;
import com.vision.core.cm.db.data.User;

/**
 * 
 * @author Mark
 *
 */
public class CreateUserWindow implements IsWidget, Editor<User> {
	
	interface Binder extends UiBinder<Widget, CreateUserWindow> { }
	
	private static final Binder binder = GWT.create(Binder.class);
	
	@UiField VerticalLayoutContainer formContainer;
	
	// Form fields that are bound by the form driver to the fields in the User class.
	// The name of these form fields must match the name of the field in the User class. 
	@UiField TextField username;
	@UiField PasswordField password;
	@UiField TextField email;
	@UiField TextField firstName;
	@UiField TextField lastName;
	
	// Ignored by the form driver since these are not fields in the User
	@Ignore @UiField TextButton saveBtn;
	@Ignore @UiField TextButton cancelBtn;
	
	@UiField Window window;
	
	interface UserDriver extends SimpleBeanEditorDriver<User, CreateUserWindow> { }
	
	private UserDriver driver = GWT.create(UserDriver.class); // Used to bind the grid to the form editor
	
	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	@Override
	public Widget asWidget() {
		window = (Window) binder.createAndBindUi(this);
		window.getHeader().setIcon(AdminResources.INSTANCE.users());
		
		{
			// TODO: Experimental
			ToolTipConfig config = new ToolTipConfig("Enter the user's name. Once saved, this cannot be modified.");
			config.setAnchor(Side.LEFT);
			config.setAnchorToTarget(true);
			config.setMaxWidth(200);
			config.setMouseOffsetY(0);
			username.setToolTipConfig(config);
			
			SideErrorHandler seh = new SideErrorHandler(username);
			seh.setAdjustTargetWidth(false);
			username.setErrorSupport(seh);
		}
		
		username.addValidator(CoreValidators.USERNAME_VALIDATOR);
		email.addValidator(CoreValidators.EMAIL_VALIDATOR);
		firstName.addValidator(CoreValidators.NAME_VALIDATOR);
		lastName.addValidator(CoreValidators.NAME_VALIDATOR);
		
		driver.initialize(this);
		driver.edit(new User());
		
		return window;
	}
	
	// UiFactory Methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	// Logic %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	@UiHandler("saveBtn")
	void saveClicked(SelectEvent e) {
		User user = driver.flush();
		if (driver.hasErrors())
			return;
		
		UI.mask(window, "Creating user...");
		// Here we try to use the command pattern using the GWT-Dispatch library
		DispatchAsync dispatch = new StandardDispatchAsync(new DefaultExceptionHandler());
		dispatch.execute(new CreateUserAction(user), new Callback<CreateUserResult>(window) {
			@Override
			protected void handleSuccess(CreateUserResult result) {
				// Close the window and fire the event
				window.hide(saveBtn);
				result.getUser().setPassword(null);
				BaseModule.fireEvent(new UserCreatedEvent(result.getUser()));
			}
		});
	}
	
	@UiHandler("cancelBtn")
	void cancelClicked(SelectEvent e) {
		window.hide(cancelBtn);
	}
	
	// Helper Methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

}
